﻿using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WJP.Logging;

namespace WJP.Log4Net
{
    /// <summary>
    /// <see cref="log4net.Core.ILogger"/>
    /// </summary>
    [Serializable]
    public class Log4NetLogger : AbstractLogger
    {
        private readonly ILog log;

        public Log4NetLogger(ILog log)
            : this(log, LogLevel.Debug)
        {
            
        }

        public Log4NetLogger(ILog log, LogLevel level)
        {
            this.log = log;
            Level = level;
            Name = GetType().FullName;
        }

        public Log4NetLogger(ILog log, string key) 
            : this(log, LogLevel.Debug, key)
        {
            
        }

        public Log4NetLogger(ILog log, Type type) 
            : this(log, LogLevel.Debug, type.FullName)
        {
            Name = type.FullName;
        }

        public Log4NetLogger(ILog log, LogLevel level, string key)
        {
            Name = key;
            Level = level;
            this.log = log;
        }

        public Log4NetLogger(ILog log, LogLevel level, Type type) 
            : this(log, level, type.FullName)
        {

        }

        public override ILogger CreateChildLogger(string loggerName)
        {
            if (loggerName.IsNullOrEmpty())
                throw new ArgumentNullException(nameof(loggerName), "子日志记录器的名称不可为空");

            return new Log4NetLogger(log, "{0}.{1}".FormatArgs(Name, loggerName));
        }

        protected override void Log(LogLevel level, string loggerName, string message, Exception exception)
        {
            if (log == null)
                return;

            if (level == LogLevel.Debug)
                log.Debug(message);
            if (level == LogLevel.Info)
                log.Info(message);
            if (level == LogLevel.Warn)
                log.Warn(message);
            if (level == LogLevel.Error)
                log.Error(message);
            if (level == LogLevel.Fatal)
                log.Fatal(message);

            if (exception != null)
            {
                if (level == LogLevel.Debug)
                    log.Debug(message, exception);
                if (level == LogLevel.Info)
                    log.Info(message, exception);
                if (level == LogLevel.Warn)
                    log.Warn(message, exception);
                if (level == LogLevel.Error)
                    log.Error(message, exception);
                if (level == LogLevel.Fatal)
                    log.Fatal(message, exception);
            }
        }
    }
}
